package com.itstyle.quartz.job;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.data.redis.core.ZSetOperations.TypedTuple;

/**
 * 
 * @author zhangwenzhi
 *
 */
public class ScoreTest implements Job, Serializable {

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private RedisTemplate redisTemplate;

	/**
	 * 
	 * 
	 * 
	 * 用redis有序集合做积分排行榜，定期对榜里的积分按一定的规则重置。
	 * 假如1个星期重置一次，重置就是对当前分数做一个减法，每个人的分数不一样，重置的时候减掉的分数也不一样
	 * ，也就是说重置之后榜单里所有人的分数是不一样的。 假如现在榜单里有上万条或者上十万条数据，我现在能想到的重置方式有如下几种：
	 * 1.一条一条的重置，即先get一条出路，然后按规则得到重置后的积分，最后在set进去；
	 * 2.直接一次性把榜单里所有数据全get出来，处理完了之后再全部set回去；
	 * 3.按排名段处理，例如先处理1-500，完了501-1000，这样重复直到处理完整个榜单，也就是一次500条get然后再set。
	 * 方法一，肯定是不可行的，因为这样效率太低了。 方法二，对于上万条或者上十万条数据不知道效率如何，各位前辈有做过的吗？
	 * 方法三，如果是数据库的话这样肯定是可行的
	 * ，但是redis，假如我先处理1-500排名的数据，处理完了之后在set回去，这处理掉的500条数据肯定会打乱之前的排名
	 * ，所以这个方法应该也是不可行的。 各位各有做过类似的经历吗？求指教！
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 * 
	 */
	@Override
	public void execute(JobExecutionContext arg0) throws JobExecutionException {

		Map<String, Integer> scoreMap = new HashMap<String, Integer>();
		ZSetOperations<String, Object> zSetOps = redisTemplate.opsForZSet();

		String scoreSortKEY = "scoreUserTest";
		for (int i = 0; i < 10; i++) {// 1000个用户进行数据进行排序
			// 随机生成数字，模拟玩家的游戏得分
			int score = (int) (Math.random() * 10);

			String userScore = "user:" + i + "article:" + i;// 用户名ID+文章ID
			// zSetOps.add(scoreSortKEY, userScore, score);
		}
		// ScanOptions options=
		Cursor<TypedTuple<Object>> cursor = zSetOps.scan(scoreSortKEY,
				ScanOptions.scanOptions().count(8).build());//一下子批量的取8个
		while (cursor.hasNext()) {
			TypedTuple<Object> a = cursor.next();
			System.out.println(a.getValue() + ":     " + a.getScore());
			Object value = a.getValue();
			if (a.getScore() < 5) {
				Double oldScore = a.getScore();
				Double newscore = oldScore * 2;
				zSetOps.add(scoreSortKEY, value, newscore);
			}

		}
		// System.out.println(cursor.getCursorId());
		// TypedTuple<Object> a=cursor.next();

		// for()

		// stringRedisTemplate.opsForValue().set("aaa", "111");
		// System.out.println(stringRedisTemplate.opsForValue().get("aaa"));
		// System.out.println("大吉大利、今晚吃鸡");
	}

}
